﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.ServiceModel;

namespace RouterControl.Service
{
	public partial class RouterControlService : ServiceBase
	{
		private readonly log4net.ILog _log = log4net.LogManager.GetLogger(typeof(RouterControlService));
        private ServiceHost _host;

		public RouterControlService()
		{
			RouterControl.IO.RouterControlVersion.LogVersion();

			try
			{
				InitializeComponent();
			}
			catch (Exception e)
			{
				_log.Fatal("Failed to create service", e);

				throw;
			}
		}

		protected override void OnStart(string[] args)
		{
			_log.Info("OnStart()");

			foreach (var a in args)
				_log.Info("  argument: " + a);

			// trigger starts
			try
			{
                // trigger local db upgrade
                new Thread(o => new LocalDb.LocalDbConnector()).Start();

                // trigger singletons
				if (RouterDeviceFinder.Instance == null)
					_log.Fatal("No instance: RouterDeviceFinder");
	
				if (RouterMaster.Instance == null)
					_log.Fatal("No instance: TrafficStats");

				if (UpdateChecker.Instance == null)
					_log.Fatal("No instance: UpdateChecker");

                if (ErrorReporting.Instance == null)
                    _log.Fatal("No instance: ErrorReporting");
			}
			catch (Exception e)
			{
				_log.Fatal("Failed to trigger singletons", e);

				throw;
			}

			// trigger router search
			try
			{
				RouterDeviceFinder.Instance.EnsureFirstSearch();
			}
			catch (Exception e)
			{
				_log.Error("Failed to trigger first router search", e);
			}

			// create service
			try
			{
                _host = new ServiceHost(typeof(SingletonService2));

                _host.Faulted += new EventHandler(host_Faulted);
                _host.UnknownMessageReceived += new EventHandler<UnknownMessageReceivedEventArgs>(host_UnknownMessageReceived);

                _host.Open();
			}
			catch (Exception e)
			{
				_log.Fatal("Failed to start WSE3 service", e);

				throw;
			}

			_log.Info("WSE3 service now listening.");
		}

        private void host_UnknownMessageReceived(object sender, UnknownMessageReceivedEventArgs e)
        {
            _log.Warn("WCF host received unknown message: " + e.Message.ToString());
        }

        private void host_Faulted(object sender, EventArgs e)
        {
            _log.Warn("WCF host faulted");
        }

		protected override void OnStop()
		{
			_log.Info("OnStop()");

			try
			{
                if (_host != null)
                    _host.Close();
			}
			catch (Exception e)
			{
				_log.Error("Failed to stop WSE3 service", e);
			}
		}
	}
}
